/**
 *
 * @file gen_html_report.c
 *
 * @brief test file for html generation
 *
 * $Id: gen_html_report.c 128 2009-01-15 10:01:43Z henri.doreau $
 */

/*
 * This file is part of Tsar.
 *
 * Tsar is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Tsar is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Tsar.  If not, see <http://www.gnu.org/licenses/>.
 */



#include <gen_html_report.h>
#include <parser.h>




#if defined( TEST_HTML )
/*
   make
   rm main.o
   gcc  -Wall -pedantic -g -pipe  -I./includes -I/usr/include -I/usr/local/include  -D_GNU_SOURCE -DIPV4_ONLY -DTEST_HTML -D_FORTIFY_SOURCE=2 -c  gen_html_report.c -o gen_html_report.o
   gcc -o tsar_test options.o utils.o tsar.o output.o sniffer.o webserver.o sockpool.o parser.o http_server.o gen_html_report.o  -L/usr/lib  -lm -lpcap
   ./tsar_test
*/

#define TEST_HTML_COLUMNS_NUMBER    3


int main( int argc, char **argv )
{
    stats_t * statTab;
    /* generated file and its associated CSS */
    FILE * fileReport, * fileCss;


    if ( argc != 2 && argc != 3 )
    {
        fprintf( stderr, "Usage : %s [filename] [pcap bpf]\n", argv[0] );
        return 1;
    }

       printf("HEre1\n");
    if ( ( statTab = make_stats_from_file( argv[1], argv[2] ) ) == NULL )
    {
        fprintf( stderr, "Failed!\n" );
        return 2;
    }

     printf("HEre2\n");

    fileReport = Fopen( "web/"REPORT_FILENAME, "w+" );
    fileCss    = Fopen( "web/style.css", "w+" );
    
    generate_html_toppage( fileReport, statTab );
    generate_css( fileCss );
    generate_graphic( fileReport, statTab );
    end_html( fileReport );

    fclose( fileCss );
    fclose( fileReport );

    stats_free( statTab );

    return 0;
}
#endif

void generate_html_toppage( FILE * destFile, stats_t * statTab )
{
    char headerHtml[] = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\"\"http://www.w3.org/TR/html4/strict.dtd\">\n"
            "<html>\n<head>\n<title>TSAR Report</title>\n";
    char headerCss[]  = "\t<link rel=\"stylesheet\" type=\"text/css\" href=\"style.css\">\n";
    char endHeader[]  = "</head>\n<body>\n";
    char title[] = "<div id=\"title\">TSAR REPORT</div>\n\t<hr>\n<div id=\"param\">Filtering expression : ";
    char param[] = "</div>";

    if ( !statTab->paramLine )
    {
        statTab->paramLine="No filtering expression supplied";
    }

    if ( fprintf( destFile,"%s%s%s%s\n", headerHtml, headerCss, endHeader, title) > 0 )
        debug( "[GEN_HTML] Http headers correctly printed\n" );
    else
        print_error( "[GEN_HTML] Cannot print http headers" );

    if (  print_html_filtered ( destFile, statTab->paramLine ) >= 0 )
        debug( "[GEN_HTML] Http headers correctly printed\n" );
    else
        print_error( "[GEN_HTML] Cannot print http headers" );
  
    if (  fprintf( destFile,"%s\n", param ) >= 0 )
        debug( "[GEN_HTML] Http headers correctly printed\n" );
    else
        print_error( "[GEN_HTML] Cannot print http headers" );
}

void generate_css( FILE * destFile )
{
    char cssbody[]="body {\n"
        "\tbackground-color:#2d271c;\n"
        "}\n";
    char css1[]=" .graph {\n"
        "\tposition:relative;\n"
        "\tleft:50%;\n"
        "\tfont: 0.6em/2em Arial;\n"
        "\tcolor: #ddb;\n"
        "\tborder-collapse: collapse;\n"
        "\twidth: "str( GRAPH_SIZE )";\n"
        "\tmargin-left:-330px;\n"
        "\tmargin-top:20px;\n"
        "\tmargin-bottom:20px;\n"
        "}\n";
    char css2[]=".graph td {\n"
        "\tpadding:0;\n"
        "\tmargin:0;\n"
        "\tvertical-align:bottom;\n"
        "\ttext-align:center;\n"
        "\tbackground: #2d271c url(" NAME_LINE ") 15px bottom;\n"
        "}\n";
    char css3[]=".graph th {\n"
        "\tbackground: #2d271c;\n"
        "}\n";
    char css4[]=".bargraph img{\n"
        "\tdisplay:block;\n"
        "\tborder-right: 1px solid #000;\n"
        "}\n";
    char css5[]="#title {\n"
        "\talign:center;\n"
        "\tfont-size: 22px;\n"
        "\tcolor:#FFFFFF;\n"
        "\tmargin-left:40%;\n"
        "}\n";
    char css6[]="#madeBy {\n"
        "\talign:center;\n"
        "\tfont-size: 13px;\n"
        "\tcolor:#FFFFFF;\n"
        "}\n";
    char css7[]="#param {\n"
        "\tfont-size: 14px;\n"
        "\tcolor:#FFFFFF;\n"
        "}\n";

    if ( fprintf( destFile, "%s%s%s%s%s%s%s%s\n", cssbody, css1, css2, css3, css4, css5, css6, css7 ) >= 0 )
    {
        debug( "[GEN_HTML] Css file correctly printed\n" );
    }
    else
    {
        print_error( "[GEN_HTML] ERROR : Can not print Css file" );
    }
}

void yaxis_name_htmlformated( char * graphicTitle, FILE * destFile )
{
    fprintf( destFile, START_TAG_TH "%s" END_TAG_TH "\n", graphicTitle );
}

unsigned long return_maxValue( stats_t * stats )
{
    int i;
    unsigned long max=0;
    
    for ( i = 0; i < COLUMNS_PER_GRAPH; i++ )
    {
        if ( max < stats->columns[i].value )
        {
            max = stats->columns[i].value;
        }
    }
    
    return max;
}

unsigned long return_yMaxValue( unsigned long max )
{
    unsigned long compare, retVal;
    int power;

    power   = log10( max );
    compare = pow( 10, power );

    if ( ( 5 * compare ) > max ) 
    {    
        retVal = 5 * compare;
    }
    else
    {
        retVal = 10 * compare;
    }
    debug( "[GEN_HTML] YMax value = %lu\n", retVal );
    return retVal;
}

void generate_graphic_xname (FILE* destFile, stats_t* stats)
{
    int i;
    
    fprintf( destFile, START_TAG_TH );
    fprintf( destFile, END_TAG_TH "\n" );

    for( i=0; i< COLUMNS_PER_GRAPH; i++ )
        {
            fprintf( destFile, "\t" START_TAG_TH );
            fprintf( destFile, "%lu",  stats->columns[i].value );
            fprintf( destFile, END_TAG_TH "\n" );
        } 

}

void generate_graphic_bar( FILE * destFile, stats_t * stats )
{
    int i;
    unsigned long columnWidth, columnHeight;

    columnWidth = GRAPH_SIZE / COLUMNS_PER_GRAPH;

    for( i = 0; i < COLUMNS_PER_GRAPH; i++ )
    {   
        /* height = graph_height * column_value / Y axis maximum value */
        columnHeight = COLUMN_HEIGHT( MAX_HEIGHT, stats->columns[i].value, return_maxValue( stats ) );

        fprintf( destFile, "\t"START_TAG_TD "<img src=\"%s\" width=\"%lu\" height=\"%lu\" alt=\"%lu\" title=\"%s\" /> %s\n",
                NAME_BAR,
                columnWidth,
                ( ( columnHeight ) ? columnHeight : MINIMAL_COLUMN_HEIGHT ),
                stats->columns[i].value,
                stats->columns[i].nameX,
                END_TAG_TD );
    }
}

void generate_graphic(FILE * destFile, stats_t * stats )
{
    debug( "[GEN_HTML] Generate graphic :%u %s %s %lu \n",
            COLUMNS_PER_GRAPH,
            GRAPHIC_NAME,
            stats->columns[0].nameX,
            stats->columns[0].value );

    fprintf( destFile, "<table class=\"graph\">\n\t" START_TAG_TR );
    yaxis_name_htmlformated( GRAPHIC_NAME, destFile );
    generate_graphic_bar( destFile, stats );
    fprintf( destFile, "\n\t" END_TAG_TR "\n" );

    fprintf( destFile, "\t" START_TAG_TR "\n\t" );
    generate_graphic_xname ( destFile, stats);
    fprintf( destFile, "\t" END_TAG_TR );
    fprintf( destFile, "\n</table>" );
    
}

void end_html( FILE * destFile )
{
    fprintf( destFile,
        "<form name=\"param\" action=\"" REPORT_FILENAME "\" method=\"POST\"><p>\n\t<INPUT type=\"text\" "
        " name=\"param\" size=\"40\" value=\"Enter here a valid pcap filter\"> \n</p>"
        " <p>\n\t<INPUT type=\"submit\" value=\"Send\">\n</p>\n</form>\n"
        "\n\t<hr>\n<div id=\"madeBy\">Generated By TSAR - <a href=\"http://code.google.com/p/tsar\">http://code.google.com/p/tsar</a> - DOREAU Henri, REVERDY Camille</div>\n"
        "</body>\n</html>\n" );
}


int create_html_page ( http_t * httpHandler, char * pcapFilename ) 
{
    int errorType=0;
    stats_t * statTab;
    /* generated file and its associated CSS */
    FILE * fileReport, * fileCss;

    if ( ( statTab = make_stats_from_file( pcapFilename, httpHandler->paramLine, &errorType ) ) == NULL )
    {
        print( MESSAGE_CRITICAL, "[GEN_HTML] ERROR : Failed to generate stat file from pcap dump!\n" );
        return errorType;
    }

    fileReport = Fopen( WEB_DIRECTORY"/"REPORT_FILENAME, "w+" );
    fileCss    = Fopen( WEB_DIRECTORY"/style.css", "w+" );
    
    generate_html_toppage( fileReport, statTab );
    generate_css( fileCss );
    generate_graphic( fileReport, statTab );
    end_html( fileReport );

    fclose( fileCss );
    fclose( fileReport );

    stats_free( statTab );
    
    return 0;
}

int print_html_filtered ( FILE * file, char * string )
{
    int i=-1, modifiedChars=0;

    while ( string[++i] )
    {
        switch (string[i])
        {
            case '<':
                fprintf( file, "&lt;" );
                modifiedChars++;
                break;
            case '>':
                fprintf( file, "&gt;" );
                modifiedChars++;
                break;
            case '&':
                fprintf( file, "&amp;" );
                modifiedChars++;
                break;
            case '"':
                fprintf( file, "&quot;" );
                modifiedChars++;
                break;      
            default :
                fprintf( file, "%c", string[i] );
                break ;
        }    
    }
    return modifiedChars;
}

